package com.geoboard.controls;

import android.content.Context;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.PorterDuff.Mode;
import android.support.v4.view.MotionEventCompat;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnTouchListener;


public class BoardCreationControl extends SurfaceView 
					implements SurfaceHolder.Callback, OnTouchListener{
	/**** Members *******************************************************/
	private final int TEXTBOX_HEIGHT = 120;
	
	private SurfaceHolder surfaceHolder = null;
	
	private volatile PointF topLeftCorner = null;
	private volatile PointF bottomRightCorner = null;
	private volatile PointF lastTopLTouch = new PointF();
	private volatile PointF lastBotRTouch = new PointF();
	
	
	private boolean isTopLeftMoving = false;
	private boolean isBotRightMoving = false;
	
	private int handleRadius = 20;
	private int bounds = 40;
	
	private Paint recPaint = null;
	private Paint handlePaint = null;
	
	

	/**** Constructors **************************************************/
	public BoardCreationControl(Context context, AttributeSet attrs) {
		super(context, attrs);
		
		// view settings
		this.setBackgroundColor(Color.TRANSPARENT);                 
	    this.setZOrderOnTop(true);
	    this.setFocusable(true);
	    this.setOnTouchListener(this);
	    
	    // SurfaceHolder settings
	    surfaceHolder = this.getHolder();
	    surfaceHolder.addCallback(this);
	    surfaceHolder.setFormat(PixelFormat.TRANSPARENT); 
		
	    // other initializations
		recPaint = new Paint();
		recPaint.setAntiAlias(true);
		recPaint.setARGB(0x1f, 0x00, 0x00, 0xff);
		
		handlePaint = new Paint();
		handlePaint.setAntiAlias(true);
		handlePaint.setARGB(0x4f, 0x00, 0x00, 0x00);
	}
	
	/**** Methods ******************************************************/
	public Point getTopLeftCorner(){
		return (new Point((int)topLeftCorner.x, (int)topLeftCorner.y));
	}
	
	public Point getBottomRightCorner(){
		return (new Point((int)bottomRightCorner.x, (int)bottomRightCorner.y)); 
	}
	
	public PointF getTopLeftCornerF(){
		return topLeftCorner;
	}
	
	public PointF getBottomRightCornerF(){
		return bottomRightCorner;
	}
	
	private void drawRectangle(){
		
		if(topLeftCorner.y < TEXTBOX_HEIGHT)topLeftCorner.y = TEXTBOX_HEIGHT;
		if(bottomRightCorner.y < TEXTBOX_HEIGHT) bottomRightCorner.y = TEXTBOX_HEIGHT;
		
		Canvas c = null;					
		try{
			c = surfaceHolder.lockCanvas(null);
			
			if(c != null){
				synchronized(surfaceHolder){
					c.drawColor(0, Mode.CLEAR);
					
					c.drawRect(topLeftCorner.x, topLeftCorner.y,
								bottomRightCorner.x, bottomRightCorner.y, recPaint);
					
					
					c.drawCircle(topLeftCorner.x, topLeftCorner.y, handleRadius, handlePaint);
					
					c.drawCircle(bottomRightCorner.x, bottomRightCorner.y, handleRadius, handlePaint);
					
				}
			}
		} finally {
			if(c != null){
				surfaceHolder.unlockCanvasAndPost(c);
			}
		}	
	}
	
	public synchronized void setCanvasSize(int width, int height){
		synchronized(surfaceHolder){		
			float quarW = 0.25f * (float)width;
			float quarH = 0.25f * (float)height;
			topLeftCorner = new PointF(quarW,quarH);
			bottomRightCorner = new PointF(3*quarW,3*quarH);
		}
		drawRectangle();
	}
	
	private boolean withinBounds(float x, float y, PointF handle, int boundry){
		
		if(x <= (handle.x + boundry) && x >= (handle.x - boundry) &&
				y <= (handle.y + boundry) && y >= (handle.y - boundry)){
			return true;
		}
		
		return false;
	}
	
	/**** OnTouchListener Overrides ************************************/
	@Override
	public boolean onTouch(View v, MotionEvent event) {
		boolean caught = false;
		int action = MotionEventCompat.getActionMasked(event);
		
		int pointerCount = event.getPointerCount();
	
		
		for(int i = 0; i < pointerCount; i++){
			 float x = MotionEventCompat.getX(event, i);
			 float y = MotionEventCompat.getY(event, i);
			
			if(action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_POINTER_DOWN){	// drag starts			
				if(withinBounds(x, y, topLeftCorner, bounds)){
					isTopLeftMoving = true;		
					lastTopLTouch.set(x, y);
					caught = true;
				} 
				if(withinBounds(x, y, bottomRightCorner, bounds)){
					isBotRightMoving = true;	
					lastBotRTouch.set(x,y);
					caught = true;
				}			
				
			} else if(action == MotionEvent.ACTION_MOVE){ // dragging in progress	
				boolean redraw = false;
				if(isTopLeftMoving && withinBounds(x, y, topLeftCorner, bounds*4)){
					
					float dx = lastTopLTouch.x - x;
					float dy = lastTopLTouch.y - y;
					
					lastTopLTouch.set(x, y);
					
					topLeftCorner.set(topLeftCorner.x - dx, topLeftCorner.y - dy);
					caught = redraw = true;
						
				} 
				if(isBotRightMoving && withinBounds(x, y, bottomRightCorner, bounds*4)){
					float dx = lastBotRTouch.x - x;
					float dy = lastBotRTouch.y - y;
					
					lastBotRTouch.set(x,y);
					
					bottomRightCorner.set(bottomRightCorner.x - dx, bottomRightCorner.y - dy);	
					caught = redraw = true;
				}
				
				if(redraw) drawRectangle();			
			} else if(action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_POINTER_UP){	// drag ends
				if(isTopLeftMoving && withinBounds(4*x, 4*y, topLeftCorner, bounds*4)){
					isTopLeftMoving = false;
					caught = true;
				} 
				if(isBotRightMoving && withinBounds(4*x, 4*y, bottomRightCorner, bounds*4)){
					isBotRightMoving = false;
					caught = true;
				}				
			}
		}
		
		return caught;
	}
		
	/**** SurfaceHoldler Overrides **************************************/
	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,	int height) {		
		setCanvasSize(width, height);		
	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {}

	

	

}
